// ignore: file_names
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import '../index.dart';

/// 支付工具类
class PayUtils {
  static final PayUtils _instance = PayUtils._internal();
  factory PayUtils() => _instance;
  PayUtils._internal();

  InAppPurchase? _iap;
  StreamSubscription<List<PurchaseDetails>>? _subscription;
  List<ProductDetails> _products = [];

  bool _is_restoring = false;
  bool _is_initialized = false;
  bool _initializing = false;
  bool _is_preconnecting = false;
  DateTime? _last_connection_time;

  static const int _connection_validity_period = 60000;

  final Map<String, String> _gift_receivers = {};

  List<String> get _gift_product_ids =>
      gift_list_data.map((gift) => gift['id'] as String).toList();

  String? get _non_consumable_gift_id =>
      _gift_product_ids.isNotEmpty ? _gift_product_ids.first : null;

  bool is_non_consumable_gift(String product_id) {
    return product_id == _non_consumable_gift_id;
  }

  List<String> get _subscription_product_ids =>
      subscription_list_data.map((sub) => sub['id'] as String).toList();

  /// 预连接到商店
  Future<void> preconnect_to_store() async {
    if (_is_preconnecting) return;
    if (_last_connection_time != null &&
        DateTime.now().difference(_last_connection_time!).inMilliseconds <
            _connection_validity_period)
      return;

    _is_preconnecting = true;
    try {
      if (!_is_initialized) await ensure_initialized();
      if (_products.isEmpty) await load_products();
      _last_connection_time = DateTime.now();
    } finally {
      _is_preconnecting = false;
    }
  }

  /// 确保初始化
  Future<bool> ensure_initialized() async {
    if (_is_initialized) return true;
    if (_initializing) {
      int attempts = 0;
      while (_initializing && attempts < 10) {
        await Future.delayed(const Duration(milliseconds: 200));
        attempts++;
      }
      return _is_initialized;
    }
    return initialize();
  }

  /// 初始化内购服务
  Future<bool> initialize() async {
    if (_is_initialized) return true;
    if (_initializing) return false;
    _initializing = true;

    try {
      await _setup_IAP();
      await check_premium_status();
      await check_first_gift_status();
      _is_initialized = true;
      _last_connection_time = DateTime.now();
      return true;
    } catch (e) {
      debugPrint('初始化内购服务失败: $e');
      return false;
    } finally {
      _initializing = false;
    }
  }

  /// 设置IAP
  Future<void> _setup_IAP() async {
    try {
      _iap = InAppPurchase.instance;
      final purchase_stream = await _get_purchase_stream_with_timeout();
      _subscription = purchase_stream.listen(
        (purchases) => _handle_purchases(purchases),
        onDone: () => _subscription?.cancel(),
        onError: (e) => debugPrint('购买出错: $e'),
      );
      await load_products();
    } catch (e) {
      debugPrint('设置IAP失败: $e');
    }
  }

  /// 获取购买流，带超时处理
  Future<Stream<List<PurchaseDetails>>>
  _get_purchase_stream_with_timeout() async {
    final completer = Completer<Stream<List<PurchaseDetails>>>();
    Timer(const Duration(seconds: 3), () {
      if (!completer.isCompleted) completer.completeError('获取购买流超时');
    });

    try {
      final stream = _iap?.purchaseStream;
      if (stream != null)
        completer.complete(stream);
      else
        completer.completeError('无法获取购买流');
    } catch (e) {
      completer.completeError(e);
    }
    return completer.future;
  }

  /// 加载产品列表
  Future<bool> load_products() async {
    try {
      final is_available = await _iap?.isAvailable() ?? false;
      if (!is_available) {
        debugPrint('应用内购买不可用');
        return false;
      }

      if (_products.isNotEmpty) return true;

      final all_product_ids = [
        ..._gift_product_ids,
        ..._subscription_product_ids,
      ];
      final response = await _query_product_details_with_timeout(
        all_product_ids.toSet(),
      );
      if (response == null || response.error != null) {
        debugPrint('查询产品详情失败: ${response?.error}');
        return false;
      }

      _products = response.productDetails;
      _last_connection_time = DateTime.now();

      return _products.isNotEmpty;
    } catch (e) {
      debugPrint('加载产品列表失败: $e');
      return false;
    }
  }

  /// 查询产品详情，带超时处理
  Future<ProductDetailsResponse?> _query_product_details_with_timeout(
    Set<String> product_ids,
  ) async {
    final completer = Completer<ProductDetailsResponse?>();
    Timer(const Duration(seconds: 5), () {
      if (!completer.isCompleted) completer.completeError('查询产品详情超时');
    });

    try {
      final response = await _iap?.queryProductDetails(product_ids);
      completer.complete(response);
    } catch (e) {
      completer.completeError(e);
    }
    return completer.future;
  }

  /// 购买产品
  Future<bool> buy_product(String product_id, {String? receiver_id}) async {
    try {
      final initialized = await ensure_initialized();
      if (!initialized) {
        debugPrint('内购服务未初始化');
        return false;
      }

      if (_products.isEmpty) await load_products();
      if (!_products.any((p) => p.id == product_id)) {
        debugPrint('产品不存在: $product_id');
        return false;
      }

      if (receiver_id != null && _gift_product_ids.contains(product_id)) {
        _gift_receivers[product_id] = receiver_id;
      }

      final product = _products.firstWhere((p) => p.id == product_id);
      final purchase_param = PurchaseParam(productDetails: product);

      final is_subscription = _subscription_product_ids.contains(product_id);
      final is_first_gift = is_non_consumable_gift(product_id);
      _last_connection_time = DateTime.now();

      final completer = Completer<bool>();
      StreamSubscription<List<PurchaseDetails>>? temp_subscription;

      temp_subscription = _iap?.purchaseStream.listen((purchases) {
        for (final purchase in purchases) {
          if (purchase.productID == product_id &&
              (purchase.status == PurchaseStatus.purchased ||
                  purchase.status == PurchaseStatus.restored)) {
            if (!completer.isCompleted) completer.complete(true);
            temp_subscription?.cancel();
            break;
          } else if (purchase.productID == product_id &&
              purchase.status == PurchaseStatus.error) {
            if (!completer.isCompleted) completer.complete(false);
            temp_subscription?.cancel();
            break;
          }
        }
      });

      if (is_subscription || is_first_gift) {
        await _iap?.buyNonConsumable(purchaseParam: purchase_param);
      } else {
        await _iap?.buyConsumable(purchaseParam: purchase_param);
      }

      return await completer.future;
    } catch (e) {
      debugPrint('购买产品失败: $e');
      return false;
    }
  }

  /// 恢复购买
  Future<void> restore_purchases() async {
    if (_is_restoring) return;
    _is_restoring = true;

    try {
      final initialized = await ensure_initialized();
      if (!initialized) {
        debugPrint('内购服务未初始化，无法恢复购买');
        return;
      }

      await _iap?.restorePurchases();
      await Future.delayed(const Duration(seconds: 2));
    } catch (e) {
      debugPrint('恢复购买失败: $e');
    } finally {
      _is_restoring = false;
    }
  }

  /// 处理购买结果
  void _handle_purchases(List<PurchaseDetails> purchases) async {
    if (purchases.isEmpty) return;

    for (final purchase in purchases) {
      switch (purchase.status) {
        case PurchaseStatus.purchased:
          await _handle_successful_purchase(purchase, false);
          break;
        case PurchaseStatus.restored:
          await _handle_successful_purchase(purchase, true);
          break;
        case PurchaseStatus.error:
          debugPrint('购买错误: ${purchase.error?.message}');
          await _iap?.completePurchase(purchase);
          break;
        case PurchaseStatus.canceled:
          await _iap?.completePurchase(purchase);
          break;
        case PurchaseStatus.pending:
          break;
      }
    }
  }

  /// 处理成功的购买
  Future<void> _handle_successful_purchase(
    PurchaseDetails purchase,
    bool is_restore,
  ) async {
    final product_id = purchase.productID;
    try {
      await _iap?.completePurchase(purchase);

      if (_subscription_product_ids.contains(product_id)) {
        await _process_subscription_purchase(product_id, is_restore);
      } else if (_gift_product_ids.contains(product_id)) {
        if (is_non_consumable_gift(product_id)) {
          await _process_first_gift_purchase(product_id);
        } else {
          final receiver_id = _gift_receivers[product_id];
          await _process_gift_purchase(product_id, receiver_id);
          if (receiver_id != null) _gift_receivers.remove(product_id);
        }
      }
    } catch (e) {
      debugPrint('处理购买完成出错: $e');
    }
  }

  /// 处理订阅购买
  Future<void> _process_subscription_purchase(
    String product_id,
    bool is_restore,
  ) async {
    try {
      await Storage().set_bool(Constants.is_premium, true);

      final DateTime now = DateTime.now();
      DateTime expiry_date;

      if (product_id.contains('wk')) {
        expiry_date = now.add(const Duration(days: 7)); // 一周
      } else if (product_id.contains('mo')) {
        expiry_date = now.add(const Duration(days: 30)); // 一个月
      } else if (product_id.contains('qtr')) {
        expiry_date = now.add(const Duration(days: 90)); // 三个月
      } else if (product_id.contains('ann')) {
        expiry_date = now.add(const Duration(days: 365)); // 一年
      } else {
        expiry_date = now.add(const Duration(days: 30));
      }

      await Storage().set_string(
        Constants.premium_expiry_date,
        expiry_date.toIso8601String(),
      );
    } catch (e) {
      debugPrint('处理订阅购买出错: $e');
    }
  }

  /// 处理第一个礼物购买（非消耗品）
  Future<void> _process_first_gift_purchase(String product_id) async {
    try {
      await Storage().set_bool(Constants.has_first_gift, true);

      int gift_count = 1;
      if (product_id.contains('5x')) {
        gift_count = 5;
      } else if (product_id.contains('10x')) {
        gift_count = 10;
      } else if (product_id.contains('30x')) {
        gift_count = 30;
      }

      await Storage().set_string(
        Constants.first_gift_count,
        gift_count.toString(),
      );
      await Storage().set_string(Constants.first_gift_id, product_id);
    } catch (e) {
      debugPrint('处理第一个礼物购买出错: $e');
    }
  }

  /// 处理礼物购买
  Future<void> _process_gift_purchase(
    String product_id,
    String? receiver_id,
  ) async {
    if (receiver_id == null) return;

    try {
      int gift_count = 1;
      if (product_id.contains('5x')) {
        gift_count = 5;
      } else if (product_id.contains('10x')) {
        gift_count = 10;
      } else if (product_id.contains('30x')) {
        gift_count = 30;
      }

      final gift_data = {
        'product_id': product_id,
        'receiver_id': receiver_id,
        'gift_count': gift_count,
        'timestamp': DateTime.now().millisecondsSinceEpoch,
      };

      final gift_history = Storage().get_list(Constants.gift_history);
      gift_history.add(gift_data.toString());
      await Storage().set_list(Constants.gift_history, gift_history);
    } catch (e) {
      debugPrint('处理礼物购买出错: $e');
    }
  }

  /// 检查高级会员状态
  Future<bool> check_premium_status() async {
    try {
      final is_premium = Storage().get_bool(Constants.is_premium);

      if (is_premium) {
        final expiry_date_str = Storage().get_string(
          Constants.premium_expiry_date,
        );
        if (expiry_date_str != null && expiry_date_str.isNotEmpty) {
          final expiry_date = DateTime.parse(expiry_date_str);
          final now = DateTime.now();

          if (now.isAfter(expiry_date)) {
            await Storage().set_bool(Constants.is_premium, false);
            return false;
          }
        }
      }

      return is_premium;
    } catch (e) {
      debugPrint('检查高级会员状态出错: $e');
      return false;
    }
  }

  /// 检查第一个礼物状态
  Future<bool> check_first_gift_status() async {
    try {
      final has_first_gift = Storage().get_bool(Constants.has_first_gift);
      return has_first_gift;
    } catch (e) {
      debugPrint('检查第一个礼物状态出错: $e');
      return false;
    }
  }

  List<ProductDetails> get products => _products;

  bool is_gift_product(String product_id) =>
      _gift_product_ids.contains(product_id);

  bool is_subscription_product(String product_id) =>
      _subscription_product_ids.contains(product_id);

  bool has_first_gift() => Storage().get_bool(Constants.has_first_gift);

  void dispose() {
    _subscription?.cancel();
  }
}
